home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 2
/
Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso
/
Pearls
/
tex
/
PasTeX14-BETA-6
/
SpecialHost
/
Source
/
Post.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-14
|
16KB
|
630 lines
/*
** SpecialHost for PasTeX
**
** Copyright © by Olaf Barthel & Georg Heßmann
*/
#include "Global.h"
#include "postlib.h"
/*#define DEBUG*/
#define INTOBP(x) ((float)(x*72.0)) /* converts 'inch' to 'big point' */
#define INTOSP(x) ((float)(x*72.0*65781.76)) /* converts 'inch' to 'scaled point' */
VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff);
VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff);
struct Library *PostBase;
STATIC struct PSparm PSparm;
STATIC struct BitMap *BitMap;
STATIC PLANEPTR Plane;
STATIC LONG ActivationRecord,
PlaneSize;
STATIC BOOL Transferred;
#ifdef DEBUG
STATIC struct Screen *LocalScreen;
STATIC struct Window *LocalWindow;
#endif /* DEBUG */
extern void insertftrap(void);
extern void deleteftrap(void);
STATIC VOID __saveds
CopyPage(VOID)
{
CopyMem(Plane,BitMap -> Planes[0],PlaneSize);
Transferred = TRUE;
#ifdef DEBUG
if(LocalScreen)
{
struct IntuiMessage *IntuiMessage;
CopyMem(Plane,LocalScreen -> RastPort . BitMap -> Planes[0],LocalScreen -> RastPort . BitMap -> BytesPerRow * LocalScreen -> RastPort . BitMap -> Rows);
ScreenToFront(LocalScreen);
WaitPort(LocalWindow -> UserPort);
while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
ReplyMsg(IntuiMessage);
}
#endif /* DEBUG */
}
void __saveds sigfpe(void)
{
PSsignalfpe(ActivationRecord);
}
void __saveds sigint(void)
{
PSsignalint(ActivationRecord,1);
}
struct BitMap * __regargs
ProcessPostscript(struct special_msg *Message,struct special_map *SpecialMap,struct parse_result *Result,LONG *Error)
{
*Error = 0;
BitMap = NULL;
if(PostBase = OpenLibrary("post.library",15))
{
BPTR NIL;
if(NIL = Open("NIL:",MODE_READWRITE))
{
LONG NewWidth,
NewHeight,
X_DPI = Message -> hresolution,
Y_DPI = Message -> vresolution;
STRPTR special_string = NULL, sp;
memset(&PSparm,0,sizeof(struct PSparm));
PSGetSizeDot(Result, &NewWidth, &NewHeight, &(SpecialMap -> hoffset), &(SpecialMap -> voffset));
SpecialMap -> width = NewWidth;
SpecialMap -> height = NewHeight;
PSparm . page . xoff = SpecialMap -> hoffset;
PSparm . page . yoff = SpecialMap -> voffset;
SpecialMap -> voffset = - SpecialMap -> voffset;
special_string = AllocVecPooled(1024,MEMF_ANY);
sp = special_string;
sprintf(sp,"TeXDict begin %d %d 1000 %d %d (noname) @start\n", \
(LONG) (INTOSP((float) NewWidth/(float)X_DPI) + 0.5), \
(LONG) (INTOSP((float) NewHeight/(float)Y_DPI) + 0.5), \
X_DPI, Y_DPI);
sp += strlen(sp);
sprintf(sp,"1 0 bop\nResolution neg VResolution neg vsize -72 div 1 add mul a @beginspecial\n");
sp += strlen(sp);
if(Result -> gotcontrol & GOT_HSIZE)
{
sprintf(sp,"%g @hsize ", INTOBP(Result -> hsize));
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_VSIZE)
{
sprintf(sp,"%g @vsize ", INTOBP(Result -> vsize));
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_HSCALE)
{
sprintf(sp,"%g @hscale ", Result -> hscale * 100.0);
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_VSCALE)
{
sprintf(sp,"%g @vscale ", Result -> vscale * 100.0);
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_SCALE)
{
sprintf(sp,"%g @hscale %g @vscale ", Result -> scale * 100.0, Result -> scale * 100.0);
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_HOFFSET)
{
sprintf(sp,"%g @hoffset ", INTOBP(Result -> hoffset));
sp += strlen(sp);
}
if(Result -> gotcontrol & GOT_VOFFSET)
{
sprintf(sp,"%g @voffset ", INTOBP(Result -> voffset));
sp += strlen(sp);
}
if (Result -> gotcontrol & GOT_ANGLE)
{
sprintf(sp,"%g @angle ", Result -> angle);
sp += strlen(sp);
}
if (Result -> gotcontrol & GOT_CLIP)
{
sprintf(sp,"@clip ");
sp += strlen(sp);
}
if(Result -> gotcontrol & SUFFICIENT_PS_ARGS)
{
sprintf(sp,"%g @llx %g @lly %g @urx %g @ury %g @rwi ", \
INTOBP(Result -> llx), INTOBP(Result -> lly), \
INTOBP(Result -> urx), INTOBP(Result -> ury), \
INTOBP(Result -> rwi));
sp += strlen(sp);
if(Result -> gotcontrol & GOT_RHI)
{
sprintf(sp,"%g @rhi ", INTOBP(Result -> rhi));
sp += strlen(sp);
}
}
sprintf(sp,"@setspecial\n");
sp += strlen(sp);
if(NewWidth > 30000 || NewHeight > 30000)
*Error = ERR_TOO_LARGE;
else
{
if(NewWidth < 1 || NewHeight < 1)
*Error = ERR_TOO_SMALL;
else
{
PrintLine("Page size %ld × %ld, %ld × %ld DPI",NewWidth,NewHeight,Message -> hresolution,Message -> vresolution);
if(BitMap = CreateBitMap(NewWidth,NewHeight,1,NULL,NULL))
{
if(Plane = (PLANEPTR)AllocVecPooled(PlaneSize = BitMap -> BytesPerRow * BitMap -> Rows,MEMF_ANY))
{
LONG ResultCode;
insertftrap();
PSparm . page . depth = 1;
PSparm . page . ydir = -1;
PSparm . page . xden = X_DPI;
PSparm . page . yden = Y_DPI;
PSparm . page . xsize = NewWidth;
PSparm . page . ysize = NewHeight;
PSparm . page . yheight = NewHeight;
PSparm . page . xbytes = BitMap -> BytesPerRow;
PSparm . page . len = PSparm . page . xbytes * PSparm . page . ysize;
PSparm . page . buf[0] = Plane;
PSparm . copyfunc = (APTR)CopyPage;
PSparm . infh = NIL;
PSparm . outfh = NIL;
PSparm . errfh = NIL;
ActivationRecord = PScreateact(&PSparm);
if(ActivationRecord <= errmax)
{
if(ActivationRecord)
*Error = 20000 + ActivationRecord;
else
*Error = ERR_NO_MEM;
}
else
{
ULONG Flags = PSFLAGCLEAR | PSFLAGERASE;
#ifdef DEBUG
if(LocalScreen = OpenScreenTags(NULL,
SA_Width, NewWidth,
SA_Height, NewHeight,
SA_Depth, 1,
SA_DisplayID, HIRESLACE_KEY,
SA_Quiet, TRUE,
SA_AutoScroll, TRUE,
SA_ShowTitle, FALSE,
SA_Overscan, OSCAN_STANDARD,
TAG_DONE))
{
if(!(LocalWindow = OpenWindowTags(NULL,
WA_Left, 0,
WA_Top, 0,
WA_Width, LocalScreen -> Width,
WA_Height, LocalScreen -> Height,
WA_RMBTrap, TRUE,
WA_Backdrop, TRUE,
WA_Borderless, TRUE,
WA_CustomScreen,LocalScreen,
WA_Activate, TRUE,
WA_IDCMP, IDCMP_VANILLAKEY,
TAG_DONE)))
{
CloseScreen(LocalScreen);
LocalScreen = NULL;
}
}
#endif /* DEBUG */
Transferred = FALSE;
if(Result -> psinit_file[0] && !(*Error))
{
PrintLine("Executing initialization file...");
if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_file,-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(Result -> psinit_string[0] && !(*Error))
{
PrintLine("Executing initialization string...");
if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_string,strlen(Result -> psinit_string),PSFLAGSTRING | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
/*
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/finclude.pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/finclude.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/texps.pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/texps.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/special..pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/color.pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/color.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
*/
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/tex.pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/tex.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(!(*Error))
{
PrintLine("Executing file \"%s\"...","TeX:ps/special.pro");
if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if (!(*Error))
{
PrintLine("Executing special string for @beginspecial...");
// Write(Output(),special_string,strlen(special_string));
if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
if(!(*Error))
{
PrintLine("Executing file \"%s\"...",Result -> psfile);
if(ResultCode = PSintstring(ActivationRecord,Result -> psfile,-1,PSFLAGFILE | Flags))
*Error = 20000 + ResultCode;
else
{
if(!Transferred)
{
if(ResultCode = PSintstring(ActivationRecord,"showpage",8,PSFLAGSTRING))
*Error = 20000 + ResultCode;
}
}
}
if (!(*Error))
{
PrintLine("Executing special string for @endspecial...");
sprintf(special_string,"@endspecial eop end userdict /end-hook known{end-hook}if\n");
if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
*Error = 20000 + ResultCode;
else
Flags = NULL;
}
PSdeleteact(ActivationRecord);
#ifdef DEBUG
if(LocalWindow)
{
CloseWindow(LocalWindow);
LocalWindow = NULL;
}
if(LocalScreen)
{
CloseScreen(LocalScreen);
LocalScreen = NULL;
}
#endif /* DEBUG */
}
deleteftrap();
FreeVecPooled(Plane);
}
else
*Error = ERR_NO_MEM;
if(*Error)
{
DeleteBitMap(BitMap);
BitMap = NULL;
}
}
else
*Error = ERR_NO_MEM;
}
}
Close(NIL);
if (special_string) FreeVecPooled(special_string);
}
else
*Error = ERR_NO_NIL;
CloseLibrary(PostBase);
PostBase = NULL;
}
else
*Error = ERR_NO_POST;
return(BitMap);
}
/* Here are some functions to get the size of the PostScript picture */
#define TR_ROTATION 1
#define TR_SCALING 2
#define TR_TRANSLATION 3
#define RAD(a) ((float)(a*3.1415926535358979324/180.0))
struct ctm {
float a,b,c,d,tx,ty;
};
struct bbox {
float llx, lly, urx, ury;
};
STATIC void ctm_transf(struct ctm *, float, float, int);
STATIC void point_transf(struct ctm *, float, float, float *, float *);
STATIC void bb_new(struct ctm *, struct bbox *, struct bbox *);
/* concatenates a transformation with the current transformation matrix. */
static void ctm_transf(struct ctm *ctm, float x, float y, int transformation)
{
float anew, bnew, cnew, dnew, costheta, sintheta;
switch (transformation) {
case TR_ROTATION:
costheta = cos(x);
sintheta = sin(x);
anew = ctm -> a * costheta + ctm -> c * sintheta;
bnew = ctm -> b * costheta + ctm -> d * sintheta;
cnew = - ctm -> a * sintheta + ctm -> c * costheta;
dnew = - ctm -> b * sintheta + ctm -> d * costheta;
ctm -> a = anew;
ctm -> b = bnew;
ctm -> c = cnew;
ctm -> d = dnew;
break;
case TR_SCALING:
ctm -> a *= x;
ctm -> b *= x;
ctm -> c *= y;
ctm -> d *= y;
break;
case TR_TRANSLATION:
ctm -> tx += ctm -> a * x + ctm -> c * y;
ctm -> ty += ctm -> b * x + ctm -> d * y;
break;
default:
break;
}
}
/* Given a point (x,y) and the current transformation matrix ctm, returns
the transformed point (x1,y1). */
static void point_transf(struct ctm *ctm, float x, float y, float *x1, float *y1)
{
*x1 = ctm -> a * x + ctm -> c * y + ctm -> tx;
*y1 = ctm -> b * x + ctm -> d * y + ctm -> ty;
}
/* Given the current transformation matrix and a bounding box,
returns the transformed bounding box. */
static void bb_new(struct ctm *ctm, struct bbox *bb, struct bbox *bbnew) {
float x0,y0,x1,y1,x2,y2,x3,y3,xmin,xmax,ymin,ymax;
xmin = ymin = 1.0e20;
xmax = ymax = -1.0e20;
point_transf(ctm, bb -> llx, bb -> lly, &x0, &y0);
point_transf(ctm, bb -> urx, bb -> lly, &x1, &y1);
point_transf(ctm, bb -> urx, bb -> ury, &x2, &y2);
point_transf(ctm, bb -> llx, bb -> ury, &x3, &y3);
xmin = min(xmin,x0); ymin = min(ymin,y0);
xmin = min(xmin,x1); ymin = min(ymin,y1);
xmin = min(xmin,x2); ymin = min(ymin,y2);
xmin = min(xmin,x3); ymin = min(ymin,y3);
xmax = max(xmax,x0); ymax = max(ymax,y0);
xmax = max(xmax,x1); ymax = max(ymax,y1);
xmax = max(xmax,x2); ymax = max(ymax,y2);
xmax = max(xmax,x3); ymax = max(ymax,y3);
bbnew -> llx = xmin;
bbnew -> lly = ymin;
bbnew -> urx = xmax;
bbnew -> ury = ymax;
}
/* Given a pointer to a struct 'parse_result', returns width, height,
hoffset, voffset of the picture, in inch. */
VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff)
{
float hscale=1.0, vscale=1.0,
hscale_rxi=1.0, vscale_rxi=1.0,
hoffset=0.0, voffset=0.0,
angle=0.0;
struct bbox bb, bbnew;
struct ctm ctm;
bb . llx = 0.0;
bb . lly = 0.0;
bb . urx = 8.0; /* default width = 8in */
bb . ury = 11.0; /* default height = 11in */
/* initialize the current transformation matrix with the identity matrix */
ctm.a = ctm.d = 1.0;
ctm.b = ctm.c = ctm.tx = ctm.ty = 0.0;
if (Result -> gotcontrol & GOT_HSCALE)
hscale = Result -> hscale;
if (Result -> gotcontrol & GOT_VSCALE)
vscale = Result -> vscale;
if (Result -> gotcontrol & GOT_SCALE)
hscale = vscale = Result -> scale;
if (Result -> gotcontrol & GOT_HOFFSET)
hoffset = Result -> hoffset;
if (Result -> gotcontrol & GOT_VOFFSET)
voffset = Result -> voffset;
if (Result -> gotcontrol & GOT_ANGLE)
angle = Result -> angle;
if (Result -> gotcontrol & SUFFICIENT_PS_ARGS) {
bb . llx = Result -> llx;
bb . lly = Result -> lly;
bb . urx = Result -> urx;
bb . ury = Result -> ury;
hscale_rxi = Result -> rwi / (10.0 * (bb . urx - bb . llx));
if (Result -> gotcontrol & GOT_RHI)
vscale_rxi = Result -> rhi / (10.0 * (bb. ury - bb . lly));
else
vscale_rxi = hscale_rxi;
}
/* Performs PostScript transformations */
ctm_transf(&ctm, hoffset, voffset, TR_TRANSLATION);
ctm_transf(&ctm, hscale, vscale, TR_SCALING);
ctm_transf(&ctm, RAD(angle), 0.0f, TR_ROTATION);
ctm_transf(&ctm, hscale_rxi, vscale_rxi, TR_SCALING);
ctm_transf(&ctm, (float)-bb.llx, (float)-bb.lly,TR_TRANSLATION);
bb_new(&ctm, &bb, &bbnew);
*width = bbnew . urx - bbnew . llx;
*height = bbnew . ury - bbnew . lly;
*hoff = bbnew . llx;
*voff = bbnew . lly;
/* hsize & vsize define the clipping area; the clipping area isn't
affected by scaling, translation or rotation. */
if (Result -> gotcontrol & GOT_HSIZE)
{
*width = Result -> hsize ;
*hoff = 0.0;
}
if (Result -> gotcontrol & GOT_VSIZE)
{
*height = Result -> vsize ;
*voff = 0.0;
}
}
/* Same of PSGetSize but returns width, height, hoffset, voffset
in 'dot' or 'pixels', using 'Result->hres' and 'Result->vres'. */
VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff)
{
float f_width, f_height, f_hoff, f_voff;
PSGetSize(Result, &f_width, &f_height, &f_hoff, &f_voff);
*width = (LONG)(f_width * (float) Result -> hres + 0.5);
*height = (LONG)(f_height * (float) Result -> vres + 0.5);
*hoff = (LONG)(f_hoff * (float) Result -> hres + 0.5);
*voff = (LONG)(f_voff * (float) Result -> vres + 0.5);
}